(function() {

    if (!window.dom) window.dom = function(selector) {

        var expr = [
            {
                descr: 'ID',
                regexp: /#[a-zA-Z]([-\w])+/gi,
                check: function(_selector){
                    return this.regexp.test(_selector);
                },
                getElements: function(_selector) {
                    return document.querySelector(_selector);
                }
            },
            {
                descr: 'CLASS',
                regexp: /\.[a-zA-Z]([-\w])+/gi,
                check: function(_selector){
                    return this.regexp.test(_selector);
                },
                getElements: function(_selector) {
                    if (document.querySelectorAll(_selector).length != 0) {
                        return document.querySelectorAll(_selector);
                    }
                }
            },
            {
                descr: 'ATTRIBUTE',
                regexp: /A\[(\w+-\w+){1,2}(\=\w+)?\]/gi,
                check: function(_selector){
                    return this.regexp.test(_selector);
                },
                getElements: function(_selector) {
                    if (document.querySelectorAll(_selector.substring(1)).length != 0) {
                        return document.querySelectorAll(_selector.substring(1));
                    }
                }
            }
        ];

        var result = {};
        result.elements = [];


        result.setClass = function(_className) {
            for (var i = 0; i < result.elements.length; i++) {
                    this.elements[i].className = _className;
            }
        }


        result.addClass = function(_className) {
            for (var i = 0; i < result.elements.length; i++) {
                var classesToAdd = _className.split(' ');
                for (var j = 0; j < classesToAdd.length; j++) {
                    if (this.elements[i].className.indexOf(classesToAdd[j]) == -1) {
                        this.elements[i].className += ' ' + classesToAdd[j];
                    }
                }
            }
        }


        result.removeClass = function(_className) {
            for (var i = 0; i < result.elements.length; i++) {
                var classes = this.elements[i].className.split(' ');
                for (var j = 0; j < classes.length; j++) {
                    if (classes[j] == _className) {
                        classes.splice(j, 1);
                    }
                } this.elements[i].className = classes.join(' ');
                ((this.elements[i].className == 0) && (this.elements[i].removeAttribute('class')));
            }
        }


        result.html = function(HTMLstring) {
            for (var i = 0; i < result.elements.length; i++) {
                this.elements[i].innerHTML = HTMLstring;
            }
        }


        result.click = function(f, args) {
            for (var i = 0; i < result.elements.length; i++) {
                this.elements[i].onclick = function(e) {
                    f(e, args);
                }
            }
        }


        result.getAttrValue = function(attrName) {
            var attrNames = [];
            for (var i = 0; i < result.elements.length; i++) {
                attrNames[attrNames.length] = this.elements[i].getAttribute(attrName);
            }
            return attrNames;
        }
        
        
        result.createElement = function(tag) {
            return this.elements[0].appendChild(document.createElement(tag));
        }


        for (i = 0; i < expr.length; i++) {
            if (expr[i].check(selector)) {
                var tmpElements = expr[i].getElements(selector);
                if (tmpElements) {
                    if (tmpElements.length > 0) {
                        for (var j = 0; j < tmpElements.length; j++) {
                            result.elements.push(tmpElements[j]);
                        }
                    } else {
                        result.elements.push(tmpElements);
                    }
                    break;
                } else {
                    return false;
                }
            }
        }


        if (result.elements.length == 0) {
            console.log('ERROR! Please, enter a valid selector!');
            return false;
        } else {
            return result;
        }
    }

})();